#
# Copyright 2012 ibiblio
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#@PydevCodeAnalysisIgnore

import os.path
import libtorrent as lt
from seedbank.cli.command import Command, CommandException
import seedbank.config.config_helper as config_helper
from seedbank.messaging.rabbitmq_publisher import SelfManagingRabbitMQPublisher
from seedbank.messaging.rabbitmq_connector import CONTENT_TYPE_BINARY, enable_pika_debug_log, DELIVERY_TRANSIENT
import bson

class UploadCommand(Command):
    _ACTION = 'add_torrent'

    def __init__(self, **kwargs):
        Command.__init__(self, **kwargs)
        self._publisher_klass = SelfManagingRabbitMQPublisher
        self._torrent_file = kwargs.get('torrent_file', '')
        self._info_hash = kwargs.get('info_hash', '')
        self._item_id = kwargs.get('item_id', '')
        self._verbose = kwargs.get('verbose', False)
        #enable_pika_debug_log()

    def execute(self):
        try:
            self._assert_required_params()
            if self._torrent_file:
                data = self._get_data_from_file(self._torrent_file)
            else:
                data = self._get_data_from_info_hash(self._info_hash)

            mq = self._create_publisher()
            message_dict = {
                'action': UploadCommand._ACTION,
                'item_id': self._item_id,
                'filename': os.path.basename(self._torrent_file),
                'torrent': bson.binary.Binary(data)
                }

            encoder = bson.BSON()
            message = encoder.encode(message_dict)

            mq.publish(message)
            mq.stop()
        except CommandException, e:
            self._println('Error: ' + str(e))

    def _assert_required_params(self):
        if not (self._torrent_file or self._info_hash):
            raise CommandException('Must provide either a torrent filename or an info hash')
        if not self._item_id:
            raise CommandException('Missing terasaur item id')

    def _create_publisher(self):
        routing_key = self._config.get(config_helper.MQ_SECTION, 'terasaur_queue')
        if self._verbose:
            self._println('Sending message to queue ' + routing_key)

        mq = self._publisher_klass(config=self._config,
                                   routing_key=routing_key,
                                   content_type=CONTENT_TYPE_BINARY,
                                   delivery_mode=DELIVERY_TRANSIENT,
                                   verbose=self._verbose)
        return mq

    def _get_data_from_file(self, filename):
        fp = open(filename, 'rb')
        data = fp.read()
        fp.close()
        self._check_torrent_data(data)
        return data

    def _check_torrent_data(self, data):
        decode = lt.bdecode(data)
        if not decode.has_key('info'):
            raise CommandException('Invalid torrent data (missing info key)')
        if not decode['info'].has_key('pieces'):
            raise CommandException('Invalid torrent data (missing pieces key)')

    def _get_data_from_info_hash(self, info_hash):
        raise NotImplementedError()
